﻿using System;
using System.Collections.ObjectModel;
using System.Linq;
using System.Windows;
using System.Windows.Threading;
using Oxage.CNC.Inputs;
using Oxage.Common;

namespace Oxage.Models
{
	public partial class ManualViewModel : ViewModelBase
	{
		#region Constructor
		public ManualViewModel()
		{
			this.Axes = new ObservableCollection<AxisViewModel>();
			this.ReferencePoints = new ObservableCollection<ReferencePoint>();
			this.InputControlList = new ObservableCollection<string>();

#if DEBUG
			//if (Settings.IsDesignMode)
			{
				this.Axes.Add(new AxisViewModel() { Name = "X", AxisType = AxisType.Linear, AxisMovement = AxisMovement.Absolute, CurrentValue = 100, TargetValue = 0 });
				this.Axes.Add(new AxisViewModel() { Name = "Y", AxisType = AxisType.Linear, AxisMovement = AxisMovement.Absolute, CurrentValue = 25.5, TargetValue = 10 });
				this.Axes.Add(new AxisViewModel() { Name = "Z", AxisType = AxisType.Linear, AxisMovement = AxisMovement.Relative, CurrentValue = 0, TargetValue = -25.5 });
				this.Axes.Add(new AxisViewModel() { Name = "A", AxisType = AxisType.Angular, AxisMovement = AxisMovement.Relative, CurrentValue = -123.45, TargetValue = 50.45 });

				this.ReferencePoints.Add(new ReferencePoint() { Name = "home" });
				this.ReferencePoints.Add(new ReferencePoint() { Name = "min" });
				this.ReferencePoints.Add(new ReferencePoint() { Name = "max" });

				this.InputControlList.Add("None");
				this.InputControlList.Add("Mouse");
				this.InputControlList.Add("Keyboard");
				//this.InputControlList.Add("Joystick");
			}
#endif

			//try
			//{
			//  var joystick = new Joystick();
			//  var list = joystick.GetList();
			//  joystick.Open(joystick.GetList().First().InstanceGuid);

			//  var timer = new DispatcherTimer();
			//  timer.Interval = TimeSpan.FromMilliseconds(40); //25 FPS
			//  timer.Tick += (sender, e) =>
			//  {
			//    var state = joystick.GetState();
			//    var slider = state.GetSlider();
			//    double a = -1d * slider[0] / 100d;
			//    double x = -1d * state.X / 100d;
			//    double y = -1d * state.Y / 100d;
			//    this.PointXY = new Point(x, y);
			//    this.PointZA = new Point(0, a);
			//  };
			//  timer.Start();
			//}
			//catch
			//{
			//}
		}
		#endregion

		#region Public properties
		public ObservableCollection<AxisViewModel> Axes
		{
			get
			{
				return this.axes;
			}
			set
			{
				if (this.axes != value)
				{
					this.axes = value;
					OnPropertyChanged("Axes");
					OnPropertyChanged("HasAxes");
					OnPropertyChanged("CanMoveToReferencePoint");
				}
			}
		}
		private ObservableCollection<AxisViewModel> axes;

		public ObservableCollection<ReferencePoint> ReferencePoints
		{
			get
			{
				return this.referencePoints;
			}
			set
			{
				if (this.referencePoints != value)
				{
					this.referencePoints = value;
					OnPropertyChanged("ReferencePoints");
					OnPropertyChanged("HasReferencePoints");
					OnPropertyChanged("CanMoveToReferencePoint");
				}
			}
		}
		private ObservableCollection<ReferencePoint> referencePoints;

		public ObservableCollection<string> InputControlList
		{
			get
			{
				return this.inputControlList;
			}
			set
			{
				if (this.inputControlList != value)
				{
					this.inputControlList = value;
					OnPropertyChanged("InputControlList");
				}
			}
		}
		private ObservableCollection<string> inputControlList;

		public bool HasReferencePoints
		{
			get
			{
				return (this.ReferencePoints != null && this.ReferencePoints.Count > 0);
			}
		}

		public bool HasAxes
		{
			get
			{
				return (this.Axes != null && this.Axes.Count > 0);
			}
		}

		public bool CanMoveToReferencePoint
		{
			get
			{
				if (!this.HasReferencePoints)
				{
					return false;
				}
				else if (this.Axes != null && this.Axes.Any(x => x.InProgress))
				{
					return false;
				}
				return true;
			}
		}

		public int InputControlIndex
		{
			get
			{
				return this.inputControlIndex;
			}
			set
			{
				if (this.inputControlIndex != value)
				{
					this.inputControlIndex = value;
					OnPropertyChanged("InputControlIndex");
				}
			}
		}
		private int inputControlIndex;

		public int ReferencePointIndex
		{
			get
			{
				return this.referencePointIndex;
			}
			set
			{
				if (this.referencePointIndex != value)
				{
					this.referencePointIndex = value;
					OnPropertyChanged("ReferencePointIndex");
					OnPropertyChanged("SelectedReferencePoint");
				}
			}
		}
		private int referencePointIndex;

		public ReferencePoint SelectedReferencePoint
		{
			get
			{
				return (this.ReferencePoints != null && this.ReferencePointIndex >= 0 && this.ReferencePoints.Count > this.ReferencePointIndex ? this.ReferencePoints[this.ReferencePointIndex] : null);
			}
		}

		public Point PointXY
		{
			get
			{
				return this.pointXY;
			}
			set
			{
				if (this.pointXY != value)
				{
					this.pointXY = value;
					Axis1.Position = value; //Workaround for binding
					OnPropertyChanged("PointXY");
				}
			}
		}
		private Point pointXY;

		public Point PointZA
		{
			get
			{
				return this.pointZA;
			}
			set
			{
				if (this.pointZA != value)
				{
					this.pointZA = value;
					Axis2.Position = value; //Workaround for binding
					OnPropertyChanged("PointZA");
				}
			}
		}
		private Point pointZA;
		#endregion

		#region Public methods
		public void QuickMove()
		{
			//App.View.NavigationService.Navigate("/Views/AxesView.xaml");
		}

		public void PreciseMove(AxisViewModel model)
		{
			//model.InProgress = true;
			//OnPropertyChanged("CanMoveToReferencePoint");

			//var client = new CncClient();
			//client.PreciseMoveCompleted += (sender, e) =>
			//{
			//  model.InProgress = false;
			//  OnPropertyChanged("CanMoveToReferencePoint");

			//  //Handle potential error
			//  if (e.Error != null)
			//  {
			//    MessageBox.Show(e.Error.Message, "Error", MessageBoxButton.OK);
			//    return;
			//  }
			//};
			//client.PreciseMoveAsync(App.Settings.WorkingProjectId, model);
		}

		public void MoveToReference(ReferencePoint model)
		{
			//App.ViewModel.IsLoading = true;

			//var client = new CncClient();
			//client.MoveToReferencePointCompleted += (sender, e) =>
			//{
			//  //Handle potential error
			//  if (e.Error != null)
			//  {
			//    MessageBox.Show(e.Error.Message, Loc.GetLabel("MessageBox.Error"), MessageBoxButton.OK);
			//    App.ViewModel.IsLoading = false;
			//    return;
			//  }

			//  App.ViewModel.IsLoading = false;
			//};
			//client.MoveToReferencePointAsync(App.Settings.WorkingProjectId, model);
		}

		//public void Load(ProjectInfoResponse result)
		//{
		//  if (result == null)
		//  {
		//    return;
		//  }

		//  var axes = new ObservableCollection<AxisViewModel>();
		//  if (result.Axes != null)
		//  {
		//    foreach (var axis in result.Axes)
		//    {
		//      axes.Add(new AxisViewModel() { Name = axis.Name, AxisType = AxisType.Linear });
		//    }
		//  }
		//  this.Axes = axes;

		//  this.ReferencePoints = result.ReferencePointList.ToObservableCollection();

		//  OnPropertyChanged("CanMoveToReferencePoint");
		//}
		#endregion

		public Controls.DualAxisController Axis1 { get; set; }

		public Controls.DualAxisController Axis2 { get; set; }
	}
}
